package com.boot.security;

import com.boot.dto.LoginDto;
import com.boot.dto.TokenDto;
import com.boot.entity.User;
import com.boot.utils.JWTUtil;
import com.boot.utils.RedisUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.oracle.xmlns.internal.webservices.jaxws_databinding.JavaWsdlMappingType;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

/**
 * @author: zcs
 * @data: 2021/4/15
 * @description:
 * 自定义登录过滤器,
 * 继承 SpringSecurity 提供的 AbstractAuthenticationProcessingFilter 类，实现 attemptAuthentication 方法，用于登录校验。
 * 本例中，模拟前端使用 json 格式传递参数，所以通过 objectMapper.readValue 的方式从流中获取入参，
 * 之后借用了用户名密码登录的校验，并返回权限对象
 */
public class JsonAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

//    @Autowired
//    private RedisUtil redisUtil;

    @Autowired
    private JWTUtil jwtUtil;

    private ObjectMapper objectMapper;
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }



    public JsonAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {

        // 从输入流中获取到登录的信息
        try {
            LoginDto loginUser = objectMapper.readValue(request.getInputStream(), LoginDto.class);

            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                    loginUser.getUsername(), loginUser.getPassword());
            //验证后返回Authentication对象
            Authentication authentication = getAuthenticationManager().authenticate(usernamePasswordAuthenticationToken);
            if (authentication.isAuthenticated()) {
                //验证成功之后生成token
                User user = (User) authentication.getPrincipal();
                TokenDto tokenDto = new TokenDto();


                //通过UUID生成token
                //tokenDto.setToken(UUID.randomUUID().toString());
                //通过JWTUtil生成token
                String token = jwtUtil.getToken(user.getId() + "");
                tokenDto.setToken(token);


                tokenDto.setUserId(user.getId());
                //将token存入redis
                //redisUtil.set(tokenDto.getToken(),tokenDto,15*60);

                user.setToken(tokenDto.getToken());
            }
            return authentication;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}